#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int Tc,n,m,L,V;
struct frac{
    ll p,q;
    frac(){}
    frac(ll p,ll q):p(p),q(q){}
    frac operator*(const frac &o)const{
        return frac(p*o.p,q*o.q);
    }
    frac operator*(const int &o)const{
        return frac(p*o,q);
    }
    frac operator+(const frac &o)const{
        int Q=q/__gcd(q,o.q)*o.q;
        return frac(p*Q/q+o.p*Q/o.q,Q);
    }
    frac operator/(const int &o)const{
        return frac(p,q*o);
    }
    frac operator+(const int &o)const{
        return frac(p+o*q,q);
    }
    frac operator-(const int &o)const{
        return frac(p-o*q,q);
    }
    bool operator<=(const int &o)const{
        return p<=o*q;
    }
    bool operator<(const int &o)const{
        return p<o*q;
    }
    bool operator<(const frac &o)const{
        return p*o.q<q*o.p;
    }
    bool operator<=(const frac &o)const{
        return p*o.q<=q*o.p;
    }
    bool operator!=(const frac &o)const{
        return p*o.q!=q*o.p;
    }
    int ce(){
        return (p+q-1)/q;
    }
    int fl(){
        return p/q;
    }
};
pair<int,int>st[100005],c[100005];
int top=0;
int d[100005],v[100005],a[100005];
int det[100005];
bool cmp(pair<int,int>x,pair<int,int>y){
    if(x.first!=y.first)return x.first<y.first;
    return y.second<x.second;
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    // cerr<<"qwq"<<endl;
    scanf("%d",&Tc);
    while(Tc--){
        // cerr<<"qwq"<<endl;
        scanf("%d%d%d%d",&n,&m,&L,&V);
        int cnt=0;
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&d[i],&v[i],&a[i]);
            if(a[i]==0){
                if(v[i]>V)c[++cnt]=make_pair(d[i],L);
            }
            else if(a[i]>0){
                if(v[i]>V)c[++cnt]=make_pair(d[i],L);
                else{
                    frac t=frac(V-v[i],a[i]);
                    frac p=t*v[i]+t*t*a[i]/2+d[i];
                    if(p<L)c[++cnt]=make_pair((p+1).fl(),L);
                }
            }
            else{
                if(v[i]<=V)continue;
                frac t=frac(V-v[i],a[i]);
                // cerr<<t.p<<' '<<t.q<<endl;
                frac p=t*v[i]+t*t*a[i]/2+d[i];
                // cerr<<p.p<<' '<<p.q<<endl;
                if(p<=L)c[++cnt]=make_pair(d[i],(p-1).ce());
                else c[++cnt]=make_pair(d[i],L);
            }
        }
        // for(int i=1;i<=cnt;i++)cerr<<c[i].first<<' '<<c[i].second<<endl;
        for(int i=1;i<=m;i++)scanf("%d",&det[i]);
        sort(c+1,c+cnt+1,cmp);
        top=0;
        int qwq=0;
        for(int i=1;i<=cnt;i++){
            int L=c[i].first,R=c[i].second;
            if(lower_bound(det+1,det+m+1,L)==upper_bound(det+1,det+m+1,R))continue;
            ++qwq;
            while(top>0 && c[i].second<=st[top].second)--top;
            st[++top]=c[i];
        }
        int pos=1;
        int ans=0;
        // cerr<<top<<endl;
        // for(int i=1;i<=top;i++)cerr<<st[i].first<<' '<<st[i].second<<endl;
        // return 0;
        while(pos<=top){
            // cerr<<pos<<endl;
            ++ans;
            int tmp=upper_bound(det+1,det+m+1,st[pos].second)-det-1;
            pos=upper_bound(st+1,st+top+1,make_pair(det[tmp],0x3f3f3f3f))-st;
        }
        // cerr<<"qwq"<<endl;
        printf("%d %d\n",qwq,m-ans);
    }
    return 0;
}